#ifndef _GRO_RENDERER_H__
#define _GRO_RENDERER_H__


#include "SDL.h"
#include <map>

namespace GRO
{
    
    struct GRO_ImageID
    {
        friend class Gui;
        
        private:
        unsigned int id;
        
        public:
        
        GRO_ImageID()
            : id(0)
        {}
        
        GRO_ImageID(unsigned int id)
            : id(id)
        {}
        
        void setValue(unsigned int id)
        {
            this->id = id;
        }
        
        unsigned int getValue() const
        {
            return id;
        }
        
        bool operator<(const GRO_ImageID& imageID) const
        {
            return (id < imageID.id);
        }
        
        bool operator==(const GRO_ImageID& imageID) const
        {
            return (id == imageID.id);
        }
    };
    
    class GRO_Image
    {
        private:
        GRO_ImageID id;
        
        public:
        GRO_Image()
        {}
        
        virtual ~GRO_Image()
        {}
        
    };

    class ImageMap
    {
        public:
        
        std::map<GRO_ImageID, GRO_Image*> images;
        
        GRO_ImageID add(GRO_Image* image);
        GRO_Image* get(const GRO_ImageID& id) const;
        GRO_Image* remove(const GRO_ImageID& id);
    };

    /*
    The renderer class is the abstraction for dynamic graphics backend switching.
    This one is completely empty, so it can be used as a dummy and as a base
    class.
    */
    class Renderer
    {
    public:

        SDL_PixelFormat format;

        Renderer()
        {

            format.BitsPerPixel = 24;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
            format.Rmask = 0xFF0000;
            format.Gmask = 0x00FF00;
            format.Bmask = 0x0000FF;
#else
            format.Rmask = 0x0000FF;
            format.Gmask = 0x00FF00;
            format.Bmask = 0xFF0000;
#endif
            format.Amask = 0;

        }
        Renderer(SDL_PixelFormat* Format)
        {
            if (Format != NULL)
            {
                format = *Format;
            }
        }
        virtual ~Renderer()
        {}

        virtual void Blit(SDL_Surface* image, SDL_Rect* s, SDL_Rect* d)
        {}

        virtual void Pixel(Sint16 x, Sint16 y, Uint32 color)
        {}

        virtual void LineH(Sint16 x1, Sint16 y, Sint16 x2, Uint32 color)
        {}

        virtual void LineHBlend(Sint16 x1, Sint16 y, Sint16 x2, Uint32 color, Uint8 alpha)
        {}

        virtual void LineV(Sint16 x, Sint16 y1, Sint16 y2, Uint32 color)
        {}

        virtual void LineVBlend(Sint16 x, Sint16 y1, Sint16 y2, Uint32 color, Uint8 alpha)
        {}

        virtual void Line(Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
        {}

        virtual void LineBlend(Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
        {}

        virtual void LineBlendAA(Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
        {}

        virtual void Rect(Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
        {}

        virtual void RectBlend(Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
        {}

        virtual void RectFilled(Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
        {}

        virtual void RectFilledBlend(Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
        {}

        virtual void RectFade(Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 c1, Uint32 c2, Uint32 c3, Uint32 c4)
        {}

        virtual void RectRound(Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 radius, Uint32 color)
        {}

        virtual void RectRoundFilledBlend(Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 radius, Uint32 color, Uint8 alpha)
        {}

        virtual void ArcBlend(Sint16 x, Sint16 y, Sint16 radius, float startAngle, float endAngle, Uint32 color, Uint8 alpha)
        {}


        virtual void Circle(Sint16 x, Sint16 y, Sint16 r, Uint32 color)
        {}

        virtual void CircleBlend(Sint16 x, Sint16 y, Sint16 r, Uint32 color, Uint8 alpha)
        {}

        virtual void CircleFilled(Sint16 x, Sint16 y, Sint16 r, Uint32 color)
        {}

        virtual void CircleFilledBlend(Sint16 x, Sint16 y, Sint16 r, Uint32 color, Uint8 alpha)
        {}

        virtual void EllipseFilled(Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
        {}

        virtual void EllipseFilledBlend(Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha)
        {}

        virtual void TrigonFade(Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 color1, Uint32 color2, Uint32 color3)
        {}

        virtual void ReadyDraw()
        {}

        virtual void DoneDraw()
        {}

        virtual SDL_Rect GetClip()
        {
            SDL_Rect r = {0, 0, 0, 0};
            return r;
        }

        virtual void SetClip(SDL_Rect& clip)
        {}

        virtual void DirtyAdd(SDL_Rect* rect)
        {}

        virtual void RectIntersect(const SDL_Rect& A, const SDL_Rect& B, SDL_Rect& intersection)
        {}

        virtual void PushThickness(int thickness)
        {}

        virtual int PopThickness()
        {
            return 0;
        }
        
        virtual Uint32 getColor(Uint8 r, Uint8 g, Uint8 b)
        {
            return SDL_MapRGB(&format, r, g, b);
        }
    };
    
    
}


    
    #endif
